#include "mainwidget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QAction>
#include <QFile>
#include <QPixmap>
#include <QGraphicsDropShadowEffect>
#include <QTimer>
#include <QApplication>

#include "model/datacenter.h"
#include "selfinfowidget.h"
#include "setwidget.h"
#include "model/data.h"
#include "sessiondetailwidget.h"
#include "groupsessiondetailwidget.h"
#include "addfrienddialog.h"
#include "debug.h"
#include "toast.h"

using namespace model;

MainWidget *MainWidget::instance = nullptr; // 初始化静态成员

MainWidget *MainWidget::getInstance(){
    if(instance == nullptr){
        // 此处不传入参数 以桌面为父窗口
        instance = new MainWidget();  // 第一次使用时(程序启动/登录)才创建
    }
    return instance;
}

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    this->setWindowTitle("抽象聊天室");
    this->setWindowIcon(QIcon(":/resource/image/logo.png"));
    this->setMinimumSize(990, 600);

    initMainWindow();
    initLeftWindow();
    initMidWindow();
    initRightWindow();
    initSignalSlot();
}

MainWidget::~MainWidget() {}

void MainWidget::initMainWindow(){
    QHBoxLayout* layout = new QHBoxLayout();
    layout->setSpacing(0);  // 内部元素间隔举例
    layout->setContentsMargins(0, 0, 0, 0); // 距离四个边界距离
    this->setLayout(layout);

    windowLeft = new QWidget();
    windowMid = new QWidget();
    windowRight = new QWidget();

    windowLeft->setFixedWidth(60);
    windowMid->setFixedWidth(230);
    windowRight->setMinimumWidth(700);

    windowLeft->setStyleSheet("QWidget{background-color: rgb(237, 237, 237);}");
    windowMid->setStyleSheet("QWidget{background-color: rgb(247, 247, 247);}");
    windowRight->setStyleSheet("QWidget{background-color: rgb(237, 237, 237);}");

    layout->addWidget(windowLeft);
    layout->addWidget(windowMid);
    layout->addWidget(windowRight);
}


void MainWidget::initLeftWindow(){
    // 公共样式：去除边框 + 悬浮背景色
    QString buttonStyle =
        "QPushButton {"
        "   border: none;"
        "   background-color: transparent;"
        "   border-radius: 5px;"
        "}"
        "QPushButton:hover {"
        "   background-color: rgba(225, 225, 225, 128);"
        "}"
       "QPushButton:pressed {"
       "   background-color: rgba(213, 213, 213, 200);"
       "}";

    QVBoxLayout* layout = new QVBoxLayout();
    layout->setSpacing(15);
    layout->setContentsMargins(0, 20, 0, 35);
    layout->setAlignment(Qt::AlignHCenter);  // 水平居中所有子控件
    windowLeft->setLayout(layout);

    // === 顶部按钮组 ===
    userAvatar = new QPushButton();
    userAvatar->setFixedSize(44, 44);
    userAvatar->setIconSize(QSize(44, 44));
    // 方式一: 如果直接设置图片路径 -- 即使按钮是圆角的, 图片直角矩形会把圆角撑开, 所以需要对图片进行操作
    // userAvatar->setIcon(QIcon(":/resource/image/defaultAvatar.png"));

    // 方式二: 圆角矩形
    // QPixmap srcPixmap(":/resource/image/kenan.png");
    // QPixmap roundedPixmap = model::getRoundRectPixmap(srcPixmap, QSize(44, 44), 8);
    // userAvatar->setIcon(QIcon(roundedPixmap));

    userAvatar->setToolTip("用户");
    userAvatar->setStyleSheet(R"(
        QPushButton {
           border: none;
           background-color: transparent;
           // border-radius: 5px;
        }
        )");
    layout->addWidget(userAvatar);

    sessionTabBtn = new QPushButton();
    sessionTabBtn->setFixedSize(42, 43);
    sessionTabBtn->setIconSize(QSize(27, 28));
    sessionTabBtn->setIcon(QIcon(":/resource/image/session_active.png"));
    sessionTabBtn->setToolTip("会话");
    sessionTabBtn->setStyleSheet(buttonStyle);
    layout->addWidget(sessionTabBtn);

    friendTabBtn = new QPushButton();
    friendTabBtn->setFixedSize(42, 43);
    friendTabBtn->setIconSize(QSize(27, 28));
    friendTabBtn->setIcon(QIcon(":/resource/image/friend_inactive.png"));
    friendTabBtn->setToolTip("通讯录");
    friendTabBtn->setStyleSheet(buttonStyle);
    layout->addWidget(friendTabBtn);

    applyTabBtn = new QPushButton();
    applyTabBtn->setFixedSize(42, 43);
    applyTabBtn->setIconSize(QSize(27, 28));
    applyTabBtn->setIcon(QIcon(":/resource/image/apply_inactive.png"));
    applyTabBtn->setToolTip("添加好友");
    applyTabBtn->setStyleSheet(buttonStyle);
    layout->addWidget(applyTabBtn);

    // === 弹簧：占据中间空白(下面两个都行) ===
    // QSpacerItem* verticalSpacer = new QSpacerItem(
    //     20,
    //     280,                      // 最小高度
    //     QSizePolicy::Minimum,
    //     QSizePolicy::Expanding   // 垂直方向可扩展（关键：仍能当弹簧用）
    //     );
    // layout->addSpacerItem(verticalSpacer);
    layout->addStretch();  // 等价于 addStretch(1)，数值只影响多个弹簧间的比例

    // === 底部按钮 ===
    moreSetBtn = new QPushButton();
    moreSetBtn->setFixedSize(42, 43);
    moreSetBtn->setIconSize(QSize(27, 28));
    moreSetBtn->setIcon(QIcon(":/resource/image/more_set.png"));
    moreSetBtn->setToolTip("更多设置");
    moreSetBtn->setStyleSheet(buttonStyle);
    layout->addWidget(moreSetBtn);
}


void MainWidget::initMidWindow(){
    // 1. 整体布局
    QGridLayout* layout = new QGridLayout();
    layout->setSpacing(0);
    layout->setContentsMargins(0, 20, 0, 0);
    layout->setVerticalSpacing(12);
    windowMid->setLayout(layout);

    // 2. 搜索栏
    searchEdit = model::createSearchBox(30, "搜索", 12);

    // 3. 快捷操作按钮
    addOperationBtn = new QPushButton();
    addOperationBtn->setFixedSize(30, 30);
    addOperationBtn->setIcon(QIcon(":/resource/image/cross.png"));
    addOperationBtn->setToolTip("快捷操作");
    addOperationBtn->setIconSize(QSize(20, 20));
    addOperationBtn->setStyleSheet(R"(
        QPushButton{
            border-radius: 5px;
            background-color: #EAEAEA;
        }
        QPushButton:hover {
           background-color: rgba(176, 176, 176, 128);
        }
        QPushButton:pressed {
           background-color: rgba(213, 213, 213, 200);
        }
    )");

    // 3. 布局构造
    // 为了更灵活的控制边距, 只影响第一行 -- 创建空白 QWidget / 使用 setColumnMinimumWidth（更优雅）
    layout->setColumnMinimumWidth(0, 12);  // 左边距
    layout->setColumnStretch(1, 1);        // 搜索框列可伸展
    layout->setColumnMinimumWidth(2, 7);   // 中间间距
    layout->setColumnMinimumWidth(4, 13);  // 右边距
    // 添加控件
    layout->addWidget(searchEdit, 0, 1);
    layout->addWidget(addOperationBtn, 0, 3);

    // 4. 会话好友区
    sessionFriendArea = new SessionFriendArea();
    if(!sessionFriendArea){
        LOG() << "sessionFriendArea";
    }
    layout->addWidget(sessionFriendArea, 1, 0, 1, 5);
}

void MainWidget::initRightWindow(){
    // 1. 创建布局管理器
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setSpacing(0);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setAlignment(Qt::AlignTop);
    windowRight->setLayout(layout);

    // 2. 创建上方标题栏
    QWidget* titleWidget = new QWidget();
    titleWidget->setFixedHeight(61);
    titleWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    titleWidget->setObjectName("titleWidget");  // 防止级联问题
    titleWidget->setStyleSheet(R"(
        #titleWidget{
            border-bottom: 1px solid rgb(213, 213, 213);
            border-left: 1px solid rgb(213, 213, 213);
        })");
    layout->addWidget(titleWidget);

    // 3. 给标题栏添加布局
    QHBoxLayout* hlayout = new QHBoxLayout();
    hlayout->setContentsMargins(20, 20, 20, 12);
    hlayout->setSpacing(10);
    titleWidget->setLayout(hlayout);

    // 标题 label
    sessionTitleLabel = new QLabel();
    sessionTitleLabel->setStyleSheet(R"(
        QLabel {
            font-size: 18px;
            font-weight: 500;
            color: #333;
        }
    )");
    sessionTitleLabel->setText("这里是会话标题");
    sessionTitleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    hlayout->addWidget(sessionTitleLabel);

    // 更多按钮
    extraBtn = new QPushButton();
    extraBtn->setIcon(QIcon(":/resource/image/more.png"));
    extraBtn->setIconSize(QSize(24, 24));
    extraBtn->setFixedSize(30, 30);
    extraBtn->setStyleSheet(R"(
        QPushButton {
            background-color: rgb(237, 237, 237);
            border: none;
            border-radius: 4px;
        }
        QPushButton:hover {
            background-color: rgb(225, 225, 225);
        }
        QPushButton:pressed {
            background-color: rgb(213, 213, 213);
        }
    )");
    extraBtn->setCursor(Qt::PointingHandCursor);
    extraBtn->setFocusPolicy(Qt::NoFocus);  // 去除虚线框
    hlayout->addWidget(extraBtn);

    // 4. 添加消息展示区
    messageShowArea = new MessageShowArea();
    layout->addWidget(messageShowArea);

    // 5. 添加消息编辑区
    messageEditArea = new MessageEditArea();
    layout->addWidget(messageEditArea, 0, Qt::AlignBottom); // 不考虑拉伸
}

void MainWidget::initSignalSlot(){
    model::DataCenter* dataCenter = model::DataCenter::getInstance();

    /*------------------ 连接信号槽, 处理标签页切换问题 ----------------*/
    connect(sessionTabBtn, &QPushButton::clicked, this, &MainWidget::switchTabToSession);
    connect(friendTabBtn, &QPushButton::clicked, this, &MainWidget::switchTabToFriend);
    connect(applyTabBtn, &QPushButton::clicked, this, &MainWidget::switchTabToApply);

    /*------------------ 连接信号槽, 显示个人主页 ----------------*/
    connect(userAvatar, &QPushButton::clicked, this, [=](){
        if (!this || this->isHidden()) {
            return; // 防止 this 已被销毁
        }
        SelfInfoWidget* selfInfoWidget = new SelfInfoWidget(this);
        selfInfoWidget->exec(); // 模态对话框
    });

    /*------------------ 连接信号槽, 显示更多设置 ----------------*/
    connect(moreSetBtn, &QPushButton::clicked, this, &MainWidget::onMoreSetBtnClicked);
    /*------------------ 连接信号槽, 显示快捷操作 ----------------*/
    connect(addOperationBtn, &QPushButton::clicked, this, &MainWidget::OnOperationBtnClicked);

    /*------------------ 点击会话详情, 显示会话详情窗口 ----------------*/
    connect(extraBtn, &QPushButton::clicked, this, [=](){
#if TEST_UI
        // 先判断是单聊还是群聊
        bool isSingleChat = false;  // 根据当前选中的实际会话来判断 -- 后续才能判断
        if(isSingleChat){
            UserInfo userinfo;
            userinfo.avatar = QIcon(":/resource/image/kenan.png");
            userinfo.nickname = "island-sunrise";
            // 单聊
            SessionDetailWidget* sessionDetailWidget = new SessionDetailWidget(this, userinfo);
            sessionDetailWidget->exec();
        }else{
            // 群聊
            GroupSessionDetailWidget* groupSessionDetailWidget = new GroupSessionDetailWidget(this);
            groupSessionDetailWidget->exec();
        }
#endif
        // 获取当前会话详细信息
        ChatSessionInfo* chatSessionInfo = dataCenter->findChatSessionById(dataCenter->getCurrentChatSessionId());
        if (chatSessionInfo == nullptr) {
            LOG() << "当前会话不存在, 无法弹出会话详情对话框";
            return;
        }

        bool isSingleChat = chatSessionInfo->userId != "";
        if (isSingleChat) {
            // 单聊, 弹出这个窗口
            UserInfo* userInfo = dataCenter->findFriendById(chatSessionInfo->userId);
            if (userInfo == nullptr) {
                LOG() << "单聊会话对应的用户不存在, 无法弹出会话详情窗口";
                return;
            }
            SessionDetailWidget* sessionDetailWidget = new SessionDetailWidget(this, *userInfo);
            sessionDetailWidget->exec();
        } else {
            // 群聊, 弹出另一个窗口
            GroupSessionDetailWidget* groupSessionDetailWidget = new GroupSessionDetailWidget(this);
            groupSessionDetailWidget->exec();
        }

    });

    /*------------------ 修改搜索框内容, 弹出添加好友窗口 ----------------*/
    // QLineEdit::textEdited(有内容就跳转)
    connect(searchEdit, &QLineEdit::returnPressed, this, [=](){
        const QString& searchKey = searchEdit->text();
        if (!searchKey.isEmpty()) {  // 确保有内容才执行
            AddFriendDialog* addFriendDialog = new AddFriendDialog(this);
            addFriendDialog->setSearchKey(searchKey);

            searchEdit->clear();  // 更好的清空方式
            addFriendDialog->exec();
        }
    });

    /*------------------ 获取个人信息 ----------------*/
    connect(dataCenter, &DataCenter::getMyselfDone, this, [=]() {
        // 从 DataCenter 中拿到响应结果的 myself, 把里面的头像取出来, 显示到界面上.
        auto myself = dataCenter->getMyself();
        userAvatar->setIcon(myself->avatar);
    });
    dataCenter->getMyselfAsync();


    /*------------------ 获取列表 ----------------*/
    loadFriendList();   // 好友列表
    loadSessionList();  // 会话列表
    loadApplyList();    // 好友申请列表

    /*------------------ 处理修改头像 ----------------*/
    connect(dataCenter, &DataCenter::changeAvatarDone, this, [=](){
        UserInfo* myself = dataCenter->getMyself();
        userAvatar->setIcon(myself->avatar);
    });

    /*------------------ 处理删除好友 ----------------*/
    connect(dataCenter, &DataCenter::deleteFriendDone, this, [=]() {
        // 更新会话列表和好友列表
        this->updateFriendList();
        this->updateChatSessionList();
        LOG() << "删除好友完成";
    });
    connect(dataCenter, &DataCenter::clearCurrentSession, this, [=]() {
        sessionTitleLabel->setText("");
        messageShowArea->clear();
        dataCenter->setCurrentChatSessionId("");
        LOG() << "清空当前会话完成";
    });

    /*------------------ 处理添加好友申请 ----------------*/
    connect(dataCenter, &DataCenter::addFriendApplyDone, this, [=](){
        Toast::showMessage("好友申请已发送");
    });

    /*------------------ 处理添加好友申请推送数据 ----------------*/
    connect(dataCenter, &DataCenter::receiveFriendApplyDone, this, [=](){
        this->updateApplyList();
        Toast::showMessage("收到新的好友申请");
    });

    /*------------------ 处理同意好友申请 ----------------*/
    connect(dataCenter, &DataCenter::acceptFriendApplyDone, this, [=](){
        this->updateApplyList();
        this->updateFriendList();
        Toast::showMessage("好友已经添加完成");
    });

    /*------------------ 处理拒绝好友申请 ----------------*/
    connect(dataCenter, &DataCenter::rejectFriendApplyDone, this, [=]() {
        // 需要更新好友申请列表. 刚才拒绝的这一项, 是需要删除掉的.
        this->updateApplyList();
        Toast::showMessage("好友申请已经拒绝");
    });

    /*------------------ 处理好友申请结果的推送数据 ----------------*/
    connect(dataCenter, &DataCenter::receiveFriendProcessDone, this, [=](const QString& nickname, bool agree) {
        if (agree) {
            // 同意
            this->updateFriendList();
            Toast::showMessage(nickname + " 已经同意了你的好友申请");
        } else {
            // 拒绝
            Toast::showMessage(nickname + " 已经拒绝了你的好友申请");
        }
    });

    /*------------------ 处理创建群聊的响应信号 ----------------*/
    connect(dataCenter, &DataCenter::createGroupChatSessionDone, this, [=](){
        Toast::showMessage("创建群聊会话已发送");
    });

    /*------------------ 处理创建会话的推送数据 ----------------*/
    connect(dataCenter, &DataCenter::receiveSessionCreateDone, this, [=]() {
        this->updateChatSessionList();
        // 通知用户, 入群
        Toast::showMessage("您被拉入到新的群聊中!");
    });
}



void MainWidget::switchTabToSession(){
    // 1. 记录当前切换到哪个标签页
    activeTab = SESSION_LIST;
    // 2. 调整图标显示
    sessionTabBtn->setIcon(QIcon(":/resource/image/session_active.png"));
    friendTabBtn->setIcon(QIcon(":/resource/image/friend_inactive.png"));
    applyTabBtn->setIcon(QIcon(":/resource/image/apply_inactive.png"));

    sessionFriendArea->clear(); // 先清空之前数据
    // 3. 在主窗口中间部分, 加载出会话列表数据
    this->loadSessionList();
}

void MainWidget::switchTabToFriend(){
    // 1. 记录当前切换到哪个标签页
    activeTab = FRIEND_LIST;
    // 2. 调整图标显示
    sessionTabBtn->setIcon(QIcon(":/resource/image/session_inactive.png"));
    friendTabBtn->setIcon(QIcon(":/resource/image/friend_active.png"));
    applyTabBtn->setIcon(QIcon(":/resource/image/apply_inactive.png"));

    sessionFriendArea->clear();
    // 3. 在主窗口中间部分, 加载出会话列表数据
    this->loadFriendList();
}

void MainWidget::switchTabToApply(){
    // 1. 记录当前切换到哪个标签页
    activeTab = APPLY_LIST;
    // 2. 调整图标显示
    sessionTabBtn->setIcon(QIcon(":/resource/image/session_inactive.png"));
    friendTabBtn->setIcon(QIcon(":/resource/image/friend_inactive.png"));
    applyTabBtn->setIcon(QIcon(":/resource/image/apply_active.png"));

    sessionFriendArea->clear();
    // 3. 在主窗口中间部分, 加载出会话列表数据
    this->loadApplyList();
}

void MainWidget::switchSession(const QString &userId){
    // 1. 在会话列表中, 先找到对应的会话元素
    DataCenter* dataCenter = DataCenter::getInstance();
    ChatSessionInfo* chatSessionInfo = dataCenter->findChatSessionByUserId(userId);
    if (chatSessionInfo == nullptr) {
        // 正常来说, 每个好友, 都会有一个对应的会话(哪怕从来没说过话).
        // 添加好友的时候, 就创建出来的会话.
        LOG() << "[严重错误] 当前选中的好友, 对应的会话不存在!";
        return;
    }

    // 2. 把选中的会话置顶, 把这个会话信息放到整个会话列表的第一个位置.
    //    后续在界面显示的时候, 就是按照列表的顺序, 从前往后显示的.
    dataCenter->topChatSessionInfo(*chatSessionInfo);

    // 3. 切换到会话列表标签页
    switchTabToSession();

    // 4. 加载这个会话对应的历史消息. 刚刚做了一个 "置顶操作" , 被选中的好友对应的会话, 在会话列表的最前头, 也就是 0 号下标.
    sessionFriendArea->clickItem(0);
}

void MainWidget::onMoreSetBtnClicked(){
    if (!setWidget) {
        setWidget = new SetWidget(this);
        connect(setWidget, &QWidget::destroyed, this, [this]() {
            setWidget = nullptr;
        });
    }

    // 显示 SetWidget。此时它的尺寸会根据布局计算完成（如果 setFixedSize 被移除）
    // 或者固定尺寸会生效。
    setWidget->show();
    setWidget->raise();
    setWidget->activateWindow();

    // 使用 singleShot 延迟计算和设置位置
    // 这会给 Qt 足够的时间来处理 SetWidget 的布局和尺寸计算
    // 0毫秒表示尽快执行，但在当前事件循环结束后
    QTimer::singleShot(0, this, [this]() {
        if (!setWidget || !moreSetBtn) { // 安全检查，确保控件仍然存在
            return;
        }

        // 1. 获取更多按钮 (extraButton) 的全局几何信息
        QPoint topLeftGlobal = moreSetBtn->mapToGlobal(moreSetBtn->rect().topLeft());
        QPoint bottomRightGlobal = moreSetBtn->mapToGlobal(moreSetBtn->rect().bottomRight());
        QRect btnRectGlobal(topLeftGlobal, bottomRightGlobal);

        // 2. 计算面板的期望位置 (微信风格：面板右下角与按钮右下角对齐，然后向上弹出)
        QPoint pos;
        pos.setX(btnRectGlobal.right() - setWidget->width());
        pos.setY(btnRectGlobal.top() - setWidget->height());

        // 3. 边界检查：防止面板超出屏幕
        QRect screen = QApplication::primaryScreen()->availableGeometry();

        if (pos.x() < screen.left()) {
            pos.setX(screen.left());
        }
        if (pos.x() + setWidget->width() > screen.right()) {
            pos.setX(screen.right() - setWidget->width());
        }
        if (pos.y() < screen.top()) {
            pos.setY(screen.top());
        }
        if (pos.y() + setWidget->height() > screen.bottom()) {
            pos.setY(screen.bottom() - setWidget->height());
            if (pos.y() < screen.top()) {
                pos.setY(screen.top());
            }
        }

        // 4. 移动到最终计算的位置
        setWidget->move(pos);
    });
}

void MainWidget::OnOperationBtnClicked()
{
    AddOperationWidget* operationWidget = new AddOperationWidget();
    operationWidget->setAttribute(Qt::WA_DeleteOnClose);

    operationWidget->show(); // 先 show，让 Qt 计算实际大小
    operationWidget->raise();
    operationWidget->activateWindow();

    // 重新计算位置
    QPoint buttonCenter = addOperationBtn->mapToGlobal(QPoint(addOperationBtn->width()/2, addOperationBtn->height()/2));

    int windowX = buttonCenter.x() - operationWidget->width()/2;
    int windowY = buttonCenter.y() + 10;

    operationWidget->move(windowX, windowY);
}


/* ----------------------- 加载数据 ---------------------- */
// 加载会话列表
void MainWidget::loadSessionList(){
    // 先判定会话列表数据是否在本地 (DataCenter) 中存在. 如果本地存在, 直接构造界面内容.
    // 如果本地不存在, 则从服务器获取数据.
    DataCenter* dataCenter = DataCenter::getInstance();
    if (dataCenter->getChatSessionList() != nullptr) {
        // 从内存加载数据显示
        updateChatSessionList();
    } else {
        // 从网络加载数据
        connect(dataCenter, &DataCenter::getChatSessionListDone, this, &MainWidget::updateChatSessionList, Qt::UniqueConnection);
        dataCenter->getChatSessionListAsync();
    }
}
void MainWidget::updateChatSessionList(){
    if(activeTab != SESSION_LIST){
        return;
    }
    DataCenter* dataCenter = DataCenter::getInstance();
    QList<ChatSessionInfo>* chatSessionList = dataCenter->getChatSessionList();

    sessionFriendArea->clear(); // 清空一下之前界面上的数据

    for (const auto& c : *chatSessionList) {
        if (c.lastMessage.messageType == TEXT_TYPE) {
            sessionFriendArea->addItem(SessionItemType, c.chatSessionId, c.avatar, c.chatSessionName, c.lastMessage.content);
        } else if (c.lastMessage.messageType == IMAGE_TYPE) {
            sessionFriendArea->addItem(SessionItemType, c.chatSessionId, c.avatar, c.chatSessionName, "[图片]");
        } else if (c.lastMessage.messageType == FILE_TYPE) {
            sessionFriendArea->addItem(SessionItemType, c.chatSessionId, c.avatar, c.chatSessionName, "[文件]");
        } else if (c.lastMessage.messageType == SPEECH_TYPE) {
            sessionFriendArea->addItem(SessionItemType, c.chatSessionId, c.avatar, c.chatSessionName, "[语音]");
        } else {
            LOG() << "错误的消息类型! messageType=" << c.lastMessage.messageType;
        }
    }
}

// 加载好友列表
void MainWidget::loadFriendList(){
    DataCenter* dataCenter = DataCenter::getInstance();
    if (dataCenter->getFriendList() != nullptr) {
        // 从内存这个列表中加载数据
        updateFriendList();
    } else {
        // 通过网络来加载数据
        connect(dataCenter, &DataCenter::getFriendListDone, this, &MainWidget::updateFriendList, Qt::UniqueConnection);
        dataCenter->getFriendListAsync();
    }
}
void MainWidget::updateFriendList(){
    if (activeTab != FRIEND_LIST) {
        // 当前的标签页不是好友列表, 就不渲染任何数据到界面上
        return;
    }
    DataCenter* dataCenter = DataCenter::getInstance();
    QList<UserInfo>* friendList = dataCenter->getFriendList();

    sessionFriendArea->clear(); // 清空一下之前界面上的数据

    // 遍历好友列表, 添加到界面上
    for (const auto& f : *friendList) {
        sessionFriendArea->addItem(FriendItemType, f.userId, f.avatar, f.nickname, f.description);
    }
}


// 加载好友申请列表
void MainWidget::loadApplyList(){
    DataCenter* dataCenter = DataCenter::getInstance();
    if (dataCenter->getApplyList() != nullptr) {
        // 本地有数据, 直接加载
        updateApplyList();
    } else {
        // 本地没有数据, 通过网络加载
        connect(dataCenter, &DataCenter::getApplyListDone, this, &MainWidget::updateApplyList, Qt::UniqueConnection);
        dataCenter->getApplyListAsync();
    }
}
void MainWidget::updateApplyList(){
    if(activeTab != APPLY_LIST) return;

    DataCenter* dataCenter = DataCenter::getInstance();
    QList<UserInfo>* applyList = dataCenter->getApplyList();
    sessionFriendArea->clear();

    for(const auto& u: *applyList){
        // 直接把这个 UserInfo 对象添加到界面上即可, 不涉及到 PB 和 自己的结构之间的转换.
        // 此处 UserInfo 的 description 不需要填写进来. 好友申请列表中, 不显示用户的签名的 (这个位置被替换成了两个按钮)
        sessionFriendArea->addItem(ApplyItemType, u.userId, u.avatar, u.nickname, "");
    }
}

void MainWidget::loadRecentMessage(const QString &chatSessionId){
    DataCenter* dataCenter = DataCenter::getInstance();
    if(dataCenter->getRecentMessageList(chatSessionId) != nullptr){
        updateRecentMessage(chatSessionId);
    }else{
        connect(dataCenter, &DataCenter::getRecentMessageListDone, this, &MainWidget::updateRecentMessage, Qt::UniqueConnection);
        dataCenter->getRecentMessageListAsync(chatSessionId, true);
    }
}

void MainWidget::updateRecentMessage(const QString &chatSessionId){
    // 1. 拿到会话的最近消息列表
    DataCenter* dataCenter = DataCenter::getInstance();
    auto* recentMessageList = dataCenter->getRecentMessageList(chatSessionId);

    // 2. 清空原有界面列表
    messageShowArea->clear();

    // 3. 显示消息列表
    for(int i = recentMessageList->size() - 1; i >= 0; --i){
        const Message& message = recentMessageList->at(i);
        bool isLeft = message.sender.userId != dataCenter->getMyself()->userId;
        messageShowArea->addFrontMessage(isLeft, message);
    }

    // 4. 设置会话标题
    ChatSessionInfo* chatSessionInfo = dataCenter->findChatSessionById(chatSessionId);
    if (chatSessionInfo != nullptr) {
        // 把会话名称显示到界面上.
        sessionTitleLabel->setText(chatSessionInfo->chatSessionName);
    }
    // 5. 保存当前选中会话
    dataCenter->setCurrentChatSessionId(chatSessionId);
    // 6. 自动把滚动条显示到末尾
    messageShowArea->scrollToEnd();
}


































